/*
 * Copyright 2007-2008, www.jsemantic.org, www.adolfoestevez.com,
 * http://semanticj2ee.blogspot.com/ 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jsemantic.servicerules.examples.energy.services;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Random;

import org.jsemantic.core.session.SemanticSession;
import org.jsemantic.servicerules.examples.energy.model.Customer;
import org.jsemantic.servicerules.examples.energy.model.Invoice;
import org.jsemantic.servicerules.examples.energy.model.MeterReading;
import org.jsemantic.servicerules.examples.energy.model.Tariff;
import org.jservicerules.support.AbstractSemanticService;
import org.jservicerules.support.annotations.SemanticService;
import org.jservicerules.support.annotations.SpringExternalContext;

/**
 * The Class InvoiceService.
 */
@SemanticService(rulesFile="org/jsemantic/support/examples/energy/tariff.drl")

@SpringExternalContext(contextFile="org/jsemantic/support/examples/energy/services.xml")

public class InvoiceService extends AbstractSemanticService {
	
	/**
	 * Creates the invoice.
	 * 
	 * @param customer the customer
	 * @param reading the reading
	 * 
	 * @return the invoice
	 */
	public Invoice createInvoice(Customer customer, MeterReading reading) {

		SemanticSession session = super.getInstance();

		session.execute(customer.getTariff());
		
		Tariff tariff = (Tariff) session.getContext().getResult("tariff");

		Invoice invoice = new Invoice();
		invoice.setNumber(generateInvoiceId());

		invoice.setDate(new Date());
		invoice.setCustomer(customer);

		BigDecimal total = calculate(tariff, reading);
		invoice.setTotal(total);

		PrinterService printerService = (PrinterService) (session.getContext()
				.getExternalContext()).getObject("printerService");

		printerService.printInvoice(invoice);

		session.dispose();
		session = null;

		return invoice;
	}

	/**
	 * Calculate.
	 * 
	 * @param tariff the tariff
	 * @param reading the reading
	 * 
	 * @return the big decimal
	 */
	private BigDecimal calculate(Tariff tariff, MeterReading reading) {

		BigDecimal totalPower = (tariff.getPpower().multiply(tariff.getPower()))
				.multiply(new BigDecimal(2));
		totalPower = totalPower.setScale(2, BigDecimal.ROUND_DOWN);

		BigDecimal totalConsume = tariff.getKwh().multiply(
				new BigDecimal(reading.getConsume()));

		totalConsume = totalConsume.setScale(2, BigDecimal.ROUND_DOWN);

		BigDecimal total = totalPower.add(totalConsume);
		total.setScale(2, BigDecimal.ROUND_DOWN);
		return total;
	}

	/**
	 * Generate invoice id.
	 * 
	 * @return the long
	 */
	private Long generateInvoiceId() {
		Random seed = new Random();
		Long id = new Long(seed.nextLong());
		if (id < 0) {
			id *= -1;
		}
		return id;
	}
}
